import { handleResponse, Result } from "../util/handler";
import { ProductAttribute } from "./product";

export interface OrderInfo {
  storeId: number;
  address: string;
  info: {
    productId: number;
    attributeId: number;
    goodQuantity: number;
  }[]
}

async function createOrder({ orderInfos, token }: { orderInfos: OrderInfo[], token: string }): Promise<Result<null>> {
  return await fetch('/api/order/createOrder', {
    method: 'post',
    credentials: 'same-origin',
    body: JSON.stringify(orderInfos),
    headers: {
      'content-type': 'application/json',
      'token': token
    }
  }).then((resp) => handleResponse<null>(resp));
}

type ProductInfo = { [P in Exclude<keyof ProductAttribute, 'attributeId' | 'stock'>]: ProductAttribute[P] } &
{ productName: string; goodQuantity: number; };
export interface BuyerSideOrder {
  orderId: number;
  address: string;
  creationTime: string;
  orderStatus: OrderStatusCode;
  storeName: string;
  info: ProductInfo[]
}

type SellerSideOrder = { [P in Exclude<keyof BuyerSideOrder, 'storeName'>]: BuyerSideOrder[P] } &
{ userId: number; orderId: number };
export type SellerSiderStoreOrder = {
  storeName: string;
  storeId: number;
  info: SellerSideOrder[];
};

async function queryUserOrders(token: string): Promise<Result<BuyerSideOrder[] | SellerSiderStoreOrder[]>> {
  return await fetch('/api/order/searchUserOrder', {
    method: 'post',
    credentials: 'same-origin',
    headers: {
      'content-type': 'application/json',
      'token': token
    }
  }).then((resp) => handleResponse<BuyerSideOrder[] | SellerSiderStoreOrder[]>(resp));
}

async function changeOrderStatus({ orderId, status, token }: { orderId: number; status: OrderStatusCode; token: string }): Promise<Result<null>> {
  return await fetch('/api/order/changeStatus', {
    method: 'post',
    credentials: 'same-origin',
    body: new URLSearchParams({ orderId: orderId+'', status: status+'' }),
    headers: {
      'content-type': 'application/x-www-form-urlencoded',
      'token': token
    }
  }).then((resp) => handleResponse<null>(resp));
}

type OrderStatus = typeof ORDER_STATUS;
type OrderStatusCode = OrderStatus[keyof OrderStatus];

const ORDER_STATUS = {
  PENDING_PAYMENT: 10,
  PAYMENT_FAILED: 12,

  PENDING_DELIVERY: 20,

  PENDING_RECEIPT: 30,
  PENDING_CONFRIMATION: 31,

  DONE: 40
} as const;

const getValidPath = (status: OrderStatusCode): OrderStatusCode[] => 
  Object.values(ORDER_STATUS)
    .filter(code => code > status);

type UserType = 'buyer' | 'seller';
// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
const getNextStatus = (userType: UserType, status: OrderStatusCode) => {
  if (userType == 'buyer') {
    return status in buyerCan ? buyerCan[status as keyof typeof buyerCan] : undefined;
  } else if (userType == 'seller') {
    return status in sellerCan ? sellerCan[status as keyof typeof sellerCan] : undefined;
  } else {
    throw new Error(`invalid userType: ${userType}`);
  }
};

const ORDER_STATUS_STRING = {
  [ORDER_STATUS.PENDING_PAYMENT]: '待支付',
  [ORDER_STATUS.PAYMENT_FAILED]: '支付失败',

  [ORDER_STATUS.PENDING_DELIVERY]: '待发货',

  [ORDER_STATUS.PENDING_RECEIPT]: '待收货',
  [ORDER_STATUS.PENDING_CONFRIMATION]: '待签收',

  [ORDER_STATUS.DONE]: '已完成'
} as const;

const buyerCan = {
  [ORDER_STATUS.PENDING_PAYMENT]: { value: ORDER_STATUS.PENDING_DELIVERY, label: '去支付' },
  [ORDER_STATUS.PENDING_CONFRIMATION]: { value: ORDER_STATUS.DONE, label: '确认收货' },
} as const;

const sellerCan = {
  [ORDER_STATUS.PENDING_PAYMENT]: [
    { value: ORDER_STATUS.PENDING_DELIVERY, label: '去发货' },
    { value: ORDER_STATUS.PAYMENT_FAILED, label: '支付失败' }
  ],
  [ORDER_STATUS.PENDING_DELIVERY]: [
    { value: ORDER_STATUS.PENDING_RECEIPT, label: '发货' },
    { value: ORDER_STATUS.DONE, label: '完成订单' }
  ],
  [ORDER_STATUS.PENDING_CONFRIMATION]: { value: ORDER_STATUS.DONE, label: '完成订单' },
} as const;


export {
  createOrder,
  queryUserOrders,
  changeOrderStatus,

  ORDER_STATUS,
  ORDER_STATUS_STRING,

  getValidPath,
  getNextStatus,
}
